/*
 * DBGestor.cpp
 *
 *  Created on: 30/11/2014
 *      Author: gustavo
 */

#include "DBGestor.h"
#include <unistd.h>
#include <iostream>
#include <ConcurrencyFiles.h>
#include <iostream>
#include <fstream>
#include <Logger.h>

#define SEPARATOR '?'

DBGestor::DBGestor() {
	Logger* log = Logger::getInstance();
	log->log(INFO,"[DBGestor] Inicializacion de la DB");
	this->db = new std::map<std::string, persona_st>;
	std::ifstream dbFile;
	log->log(INFO,"[DBGestor] Abro DB");
	dbFile.open(ConcurrencyFiles::DBPATH.c_str(), std::ofstream::in);
	std::string line;
	log->log(INFO,"[DBGestor] Leo valores existentes");
	while (getline(dbFile, line)) {
		log->log(INFO,"[DBGestor] Leo entrada");
		persona_st person;
		memset(&person,0,sizeof(persona_st));
		unsigned int namePos = line.find(SEPARATOR);
		std::string name = line.substr(0, namePos);
		line = line.substr(namePos + 1, std::string::npos);
		unsigned int dirPos = line.find(SEPARATOR);
		std::string dir = line.substr(0, dirPos);
		line = line.substr(dirPos+1, std::string::npos);
		std::string tel = line.substr(0,std::string::npos);

		log->log(INFO,"[DBGestor] Entrada leida "+ name + " " + dir + " " + tel);
		memcpy(person.nombre, name.c_str(), name.length());
		memcpy(person.direccion, dir.c_str(), dir.length());
		memcpy(person.telefono, tel.c_str(), tel.length());
		this->db->insert(std::pair<std::string, persona_st>(name, person));

	}
	log->log(INFO,"[DBGestor] Fin de inicializacion de la DB");
	dbFile.close();
}

DBGestor::~DBGestor() {
	Logger* log = Logger::getInstance();
	log->log(INFO,"[DBGestor] Persistencia de la DB");
	std::ofstream dbFile;
	log->log(INFO,"[DBGestor] Abro DB");
	dbFile.open(ConcurrencyFiles::DBPATH.c_str(), std::ofstream::out);
	for (std::map<std::string, persona_st>::iterator it = this->db->begin();
			it != this->db->end(); ++it) {
		log->log(INFO,"[DBGestor] Persito entrada");
		dbFile << it->second.nombre;
		dbFile << SEPARATOR;
		dbFile << it->second.direccion;
		dbFile << SEPARATOR;
		dbFile << it->second.telefono;
		log->log(INFO,"[DBGestor] Entrada persistida");
		dbFile << std::endl;
	}
	dbFile.close();

}

void DBGestor::add(persona_st person) {
	std::string key(person.nombre);
	if (this->db->insert(std::pair<std::string, persona_st>(key, person)).second
			== false) {
		throw("Operación agregar: Elemento ya existente en la bd");
	}
}

void DBGestor::remove(std::string personName) {
	int removeResult = this->db->erase(personName);
	if (removeResult == 0) {
		throw("Operacion remover: Elemento inexistente en la bd");
	}
}

void DBGestor::update(persona_st person) {
	std::map<std::string, persona_st>::iterator it = this->db->find(
			person.nombre);
	if (it == this->db->end()) {
		throw("Operacion actualizar: Elemento inexistente en la bd");
	} else {
		it->second = person;
	}
}
persona_st DBGestor::consult(std::string personName) {
	std::map<std::string, persona_st>::iterator it = this->db->find(personName);
	if (it == this->db->end()) {
		throw("Operacion consulsta: Elemento inexistente en la bd");
	} else {
		return it->second;
	}
}
DBGestor* DBGestor::instance = 0;

DBGestor* DBGestor::getInstance() {
	if (instance == 0) {
		instance = new DBGestor();
	}
	return instance;
}
